﻿using System.ComponentModel.DataAnnotations;
using System.Security.Claims;
using System.Security.Cryptography;
using Devonline.Identity;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ProjectManagement.Models;
using UserViewModel = ProjectManagement.Models.UserViewModel;

namespace ProjectManagement.Controllers;

[Route("api/[controller]")]
[ApiController]
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
public class AccountsController : ControllerBase
{
    private readonly ApplicationDbContext _context;
    private readonly UserManager<User> _userManager;
    private readonly IDataService<IdentityDbContext, User> _dataService;
    private readonly AppSetting _appSetting;
    public AccountsController(
        ApplicationDbContext context,
        UserManager<User> userManager,
        IDataService<IdentityDbContext, User> dataService,
        AppSetting appSetting)
    {
        _context = context;
        _userManager = userManager;
        _dataService = dataService;
        _appSetting = appSetting;
    }

    [AllowAnonymous]
    [Display(Name = "登录")]
    [HttpPost("Login")]
    public async Task<IActionResult> Login(UserViewModel userModel)
    {
        if (userModel == null)
        {
            return BadRequest("请输入用户名和密码!");
        }

        try
        {
            var password = userModel.Password.GetHashValue<SHA256>(encoding: System.Text.Encoding.UTF8);
            var user = await _dataService.GetQueryable().FirstOrDefaultAsync(x => x.UserName == userModel.UserName && x.PasswordHash == password);
            if (user != null)
            {
                if (User.Identity.IsAuthenticated)
                {
                    return Ok();
                }

                var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
                identity.AddClaim(new Claim(ClaimTypes.Sid, user.Id));
                identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
                identity.AddClaim(new Claim(ClaimTypes.GivenName, user.Name));
                identity.AddClaim(new Claim(ClaimTypes.Role, nameof(User)));
                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
                //Response.Cookies.Append(AppSettings.CACHE_SESSION + user.Id, HttpContext.Session.Id);
                return Ok();
            }
            else
            {
                const string badUserNameOrPasswordMessage = "用户名或密码错误";
                return Unauthorized(badUserNameOrPasswordMessage);
            }
        }
        catch (Exception ex)
        {
            return BadRequest(ex.Message);
        }
    }

    /// <summary>
    /// 注销接口
    /// </summary>
    /// <returns></returns>
    [Display(Name = "注销")]
    [HttpGet, HttpPost, Route("logout")]
    public async Task<IActionResult> Logout()
    {
        HttpContext.Session.Clear();
        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        return Unauthorized();
    }

    /// <summary>
    /// 重置密码接口
    /// </summary>
    /// <returns></returns>
    [Display(Name = "重置密码")]
    [HttpPost("ResetPassword")]
    public async Task<IActionResult> ResetPassword(UserViewModel userModel)
    {
        var password = userModel.OldPassword.GetHashValue<SHA256>();
        var user = await _dataService.GetQueryable().FirstOrDefaultAsync(x => x.UserName == userModel.UserName && x.PasswordHash == password);
        if (user != null && userModel.Password.IsNotNullOrEmpty() && userModel.Password == userModel.ConfirmPassword)
        {
            await _userManager.ChangePasswordAsync(user, userModel.OldPassword, userModel.Password);
            HttpContext.Session.Clear();
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            return Unauthorized();
        }
        else
        {
            const string message = "原始密码输入错误, 请重新输入密码！";
            return BadRequest(message);
        }
    }

    [Display(Name = "数据迁移")]
    [AllowAnonymous, HttpGet("AutoMigration")]
    public async Task<IActionResult> AutoMigrationAsync()
    {
        await _context.AutoMigrationAsync();
        return Ok();
    }

    [Display(Name = "添加默认管理员")]
    [AllowAnonymous, HttpGet("AddAdministrator")]
    public async Task<IActionResult> AddAdministratorAsync()
    {
        if (_context.Users.Any(x => x.UserName == AppSettings.USER_ADMINISTRATOR))
        {
            return BadRequest($"管理员账户 {AppSettings.USER_ADMINISTRATOR} 已存在!");
        }

        var user = new User
        {
            Name = "超级管理员",
            UserName = AppSettings.USER_ADMINISTRATOR,
            PasswordHash = _appSetting.DefaultPassword.GetHashValue<SHA256>(),
            Alias = "管理员"
        };

        await _dataService.AddAsync(user);
        await _dataService.SaveChangesAsync();
        return Ok();
    }
}